#include <stdio.h>
#include <octopus.h>

sbit CS = P2 ^ 7;
sbit SK = P2 ^ 6;
sbit DI = P2 ^ 5;
sbit DO = P2 ^ 4;


#define CS(x) octopus_io_set_pin(octopus, PIN, x)
#define SK(x) octopus_io_set_pin(octopus, PIN, x)
#define DI(x) octopus_io_set_pin(octopus, PIN, x)
#define DO_OUT(x) octopus_io_set_pin(octopus, PIN, x)
#define DO_IN() octopus_io_set_pin(octopus, PIN, x)


// Write enable must precede all programming modes.
void
Ewen (void)
{
  unsigned char temp, InData;
  CS = 0;
  SK = 0;
  CS = 1;
  InData = 0x98;					  // 10011XXXX
  for (temp = 9; temp != 0; temp--)
	 {									  // 9
		DI = InData & 0x80;
		SK = 1;
		SK = 0;
		InData <<= 1;
	 }
  CS = 0;
}

// Disables all programming instructions.
void
Ewds (void)
{
  unsigned char temp, InData;
  CS = 0;
  SK = 0;
  CS = 1;
  InData = 0x80;					  // 10000XXXX
  for (temp = 9; temp != 0; temp--)
	 {									  // 9
		DI = InData & 0x80;
		SK = 1;
		SK = 0;
		InData <<= 1;
	 }
  CS = 0;
}

// Reads data stored in memory, at specified address.
unsigned int
Read (unsigned char address)
{
  unsigned char temp;
  unsigned int result;
  Ewen ();
  SK = 0;
  DI = 1;							  // 110 A5-A0
  CS = 0;
  CS = 1;
  SK = 1;
  SK = 0;							  // 1
  address = address & 0x3f 0x80;
  for (temp = 8; temp != 0; temp--)
	 {									  // 8
		DI = address & 0x80;
		SK = 1;
		SK = 0;
		address <<= 1;
	 }
  DO = 1;
  for (temp = 16; temp != 0; temp--)
	 {									  // 16
		SK = 1;
		result = (result << 1) DO;
		SK = 0;
	 }
  CS = 0;
  Ewds ();
  return (result);
}

// Writes memory location An - A0.
void
Write (unsigned char address, unsigned int InData)
{
  unsigned char temp;
  Ewen ();
  SK = 0;
  DI = 1;							  // 101 A5-A0
  CS = 0;
  CS = 1;
  SK = 1;
  SK = 0;							  // 1
  address = address & 0x3f 0x40;
  for (temp = 8; temp != 0; temp--)
	 {									  // 8
		DI = address & 0x80;
		SK = 1;
		SK = 0;
		address <<= 1;
	 }
  for (temp = 16; temp != 0; temp--)
	 {									  // 16
		DI = InData & 0x8000;
		SK = 1;
		SK = 0;
		InData <<= 1;
	 }
  CS = 0;
  DO = 1;
  CS = 1;
  SK = 1;
  while (DO == 0)
	 {									  // busy test
		SK = 0;
		SK = 1;
	 }
  SK = 0;
  CS = 0;
  Ewds ();
}

/*
// Erase memory location An - A0.
void Erase(unsigned char address) {
 unsigned char temp;
 Ewen();
 SK=0; DI=1; // 111 A5-A0
 CS=0; CS=1;
 SK=1; SK=0;   // 1
 address =0xc0;
 for(temp=8;temp!=0;temp--) { // 8
  DI=address&0x80;
  SK=1; SK=0;
  address<<=1;
 }
 CS=0; DO=1;
 CS=1; SK=1;
 while(DO==0) {
  SK=0; SK=1;
 }
 SK=0; CS=0;
 Ewds();
}

// Erases all memory locations. Valid only at VCC = 4.5V to 5.5V.
void Eral(void) {
 unsigned char temp,InData;
 Ewen();
 CS=0;
 SK=0;
 CS=1;
 InData=0x90; // 10010XXXX
 for(temp=9;temp!=0;temp--) { // 9
  DI=InData&0x80;
  SK=1; SK=0;
  InData<<=1;
 }
 CS=0; DO=1;
 CS=1; SK=1;
 while(DO==0) {
  SK=0; SK=1;
 }
 SK=0; CS=0;
 Ewds();
}

// Writes all memory locations. Valid only at VCC = 4.5V to 5.5V.
void Wral(unsigned int InData) {
 unsigned char temp,address;
 Ewen();
 CS=0;
 SK=0;
 CS=1;
 address=0x88; // 10001XXXX
 for(temp=9;temp!=0;temp--) { // 9
  DI=address&0x80;
  SK=1; SK=0;
  address<<=1;
 }
 for(temp=16;temp!=0;temp--) { // 16
  DI=InData&0x8000;
  SK=1; SK=0;
  InData<<=1;
 }
 CS=0; DO=1;
 CS=1; SK=1;
 while(DO==0) {
  SK=0; SK=1;
 }
 SK=0; CS=0;
 Ewds();
}

*/




int
main ()
{

  struct octopus_context octopus;

  if (!octopus_init (&octopus))
	 printf ("%s\n", octopus.error_str);

  if (octopus_open (&octopus) < 0)
	 {
		//if(octopus_open_serial(&octopus,"20081109")<0){
		printf ("%s\n", octopus.error_str);
		exit (0);
	 }

  int i;
  char desc[64];
  octopus_get_hwdesc (&octopus, desc);
  printf ("Device: %s\n", desc);

#if 0
#define PIN 11
  if (octopus_io_init (&octopus, PIN) < 0)
	 printf ("ERROR: %s\n", octopus.error_str);

  if (octopus_io_set_pin_direction_out (&octopus, PIN) < 0)
	 printf ("ERROR: %s\n", octopus.error_str);

  for (;;)
	 {
		if (octopus_io_set_pin (&octopus, PIN, 1) < 0)
		  printf ("ERROR: %s\n", octopus.error_str);

		sleep (1);

		if (octopus_io_set_pin (&octopus, PIN, 0) < 0)
		  printf ("ERROR: %s\n", octopus.error_str);

		sleep (1);
	 }
#endif
  if (octopus_close (&octopus) < 1)
	 printf ("ERROR: %s\n", octopus.error_str);

  return 0;


}
